package com.ebook.server.service;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.ebook.core.domain.Book;
import com.ebook.core.util.BookUtil;
import com.ebook.util.ErrorCode;
import com.ebook.util.Status;
import com.ebook.util.UpAndDown;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

@Service
@Transactional
public class BookService {

	private static final String BOOK_FILE_PATH = "/opt/ebook/data/ebooks";
	//	private static final String BOOK_COVER_IMG_PATH = "/opt/ebook/data/images/cover";
	//	private static final String BOOK_FILE_PATH = "e:/svn/ebook/data/ebooks"; //TODO: modify
	//	private static final String BOOK_COVER_IMG_PATH = "e:/svn/ebook/data/images/cover";

	@Resource
	private JdbcTemplate jdbcTemplate;

	@Resource
	private FileOperateService fileOperateService;

	@Resource
	private UserService userService;

	private static Log logger = LogFactory.getLog(BookService.class);

	public ModelAndView downloadEbook(int uid, int bookid, HttpServletRequest request, HttpServletResponse response) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		String status = Status.SUCCESS;
		String filePath_Name = getBookFile(uid, bookid);
		if (filePath_Name == null) {
			status = Status.REJECTED + ":" + ErrorCode.BOOK_NOT_EXIST;
		}
		UpAndDown.continueToDownload(filePath_Name, request, response);
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
		return modelView;
	}

	/**
	 * 将图书封面图片存到数据库中
	 * @param picFile 图片文件
	 * @param bookId  图书id
	 * @return 成功失败信息
	*/
	public ModelAndView addCoverPic(MultipartFile picFile, int bookId) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		String status = Status.SUCCESS;
		if (addCoverPic(bookId, picFile) == false) {
			status = Status.REJECTED + ":" + ErrorCode.FAIL;
		}
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
		return modelView;
	}

	/**
	 * 通过图书id获取图书对象
	 * @param id 图书id
	 * @return   图书信息对象
	 */
	public Book getBookInfo(int id) {
		String sql1 = "select count(*) from book where id = ?";
		String sql2 = "select * from book where id = ?";
		Book book = null;
		try {
			if (jdbcTemplate.queryForInt(sql1, id) > 0) {
				Map<String, Object> map = jdbcTemplate.queryForMap(sql2, id);
				if (map.size() > 0) {
					book = BookUtil.parseBook(map);
				}
			}
		} catch (DataAccessException e) {
			e.printStackTrace();
			book = null;
		}

		return book;
	}

	//TODO: 
	public List<Book> getAllBooks() {
		List<Book> books = new ArrayList<Book>();

		String sql = "select * from book";
		try {
			List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
			for (Map<String, Object> map : maps) {
				Book book = BookUtil.parseBook(map);
				if (book != null) {
					books.add(book);
				}
			}
		} catch (DataAccessException e) {
			e.printStackTrace();
			return new ArrayList<Book>();
		}

		return books;
	}

	//TODO
	public List<Book> getFavBooksByUserId(int userid) {
		List<Book> books = new ArrayList<Book>();

		String sql = "select book.* from book, book_favor where book.id=book_favor.bookid and book_favor.userid=? and book_favor.status=1";
		try {
			List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, userid);
			for (Map<String, Object> map : maps) {
				Book book = BookUtil.parseBook(map);
				if (book != null) {
					books.add(book);
				}
			}
		} catch (DataAccessException e) {
			e.printStackTrace();
			return new ArrayList<Book>();
		}
		return books;
	}

	//TODO
	public boolean addFavBook(int userId, int bookId) {
		String sql = "select count(id) from book_favor where userid=? and bookid=?";
		int cnt = jdbcTemplate.queryForInt(sql, userId, bookId);
		if (cnt > 0) {
			sql = "update book_favor set status=1 where userid=? and bookid=?";
		} else {
			sql = "insert into book_favor (id, userid, bookid) values(0, ?, ?)";
		}
		int ret = jdbcTemplate.update(sql, userId, bookId);

		return ret > 0;
	}

	//TODO
	public boolean deleteFavBook(int userId, int bookId) {
		String sql = "select count(id) from book_favor where userid=? and bookid=?";
		int cnt = jdbcTemplate.queryForInt(sql, userId, bookId);
		if (cnt < 1) {
			return true;
		} else {
			sql = "update book_favor set status=0 where userid=? and bookid=?";
			int ret = jdbcTemplate.update(sql, userId, bookId);
			return ret > 0;
		}
	}

	public String getBookFileFullName(int bookId) {
		// TODO Auto-generated method stub
		return null;
	}

	//TODO
	/**
	 * 取电子书文件
	 * @return
	 */
	public String getBookFile_old(int bookId) {
		if (bookId < 0) {
			return null;
		}
		try {
			String sql = "select book_file_name from book_data where book_id = ?";
			Map<String, Object> map = jdbcTemplate.queryForMap(sql, bookId);
			if (map != null) {
				String fileName = (String) map.get("book_file_name");
				if (fileName != null) {
					fileName = bookId + "_" + fileName;
					String fileJson = fileOperateService.getFileJsonString(BOOK_FILE_PATH + "/" + fileName);
					return fileJson;
				}
			}
		} catch (DataAccessException e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 通过uid 和 bookid 获取文件路径名
	 * @param uid
	 * @param bookid
	 * @return 文件路径名 或 null
	*/
	public String getBookFile(int uid, int bookid) {
		if (bookid < 0) {
			return null;
		}
		String sql1 = "SELECT count(*) from user_book as ub,book_data as bd WHERE ub.book_id=bd.book_id and ub.user_id=? and bd.book_id=?";
		String sql2 = "SELECT bd.book_file_name from user_book as ub,book_data as bd WHERE ub.book_id=bd.book_id and ub.user_id=? and bd.book_id=?";
		//		logger.debug(sql1);
		//		logger.debug(sql2);
		try {
			if (jdbcTemplate.queryForInt(sql1, uid, bookid) > 0) {
				Map<String, Object> map = jdbcTemplate.queryForMap(sql2, uid, bookid);
				if (map != null) {
					String fileName = (String) map.get("book_file_name");
					if (fileName != null) {
						fileName = bookid + "_" + fileName;
						String filePath_Name = BOOK_FILE_PATH + "/" + fileName;
						File f = new File(BOOK_FILE_PATH);
						if (!f.exists()) {
							f.mkdirs();
						}
						return filePath_Name;
					}
				}
			} else {
				return null;
			}

		} catch (DataAccessException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 添加图书封面图片
	 * @param bookId 图书id
	 * @param file 笔记对应的数据文件,将存放在数据库中
	 * @return true。失败返回false
	 */
	public boolean addCoverPic(int bookId, MultipartFile file) {
		String sql = "update book set pic = ? where id = ?";
		try {
			byte[] data = file.getBytes();
			jdbcTemplate.update(sql, data, bookId);
			return true;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	public ModelAndView getNewBooks(int uid, String bookidsJson, HttpServletRequest request) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		List<Book> bookList = null;
		String status = Status.SUCCESS;
		//		User user = (User) request.getSession().getAttribute("loginuser");
		//		if (user == null || uid != user.getId()) {
		//			return userService.notLoginView(modelView, modelMap);
		//		}
		//		if (uid == user.getId()) {
		Gson gson = new Gson();
		List<Book> list = gson.fromJson(bookidsJson, new TypeToken<List<Book>>() {
		}.getType());
		bookList = getBookByNoBookids(uid, list);
		modelMap.put("bookList", bookList);
		//		}
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
		return modelView;

	}

	private List<Book> getBookByNoBookids(int uid, List<Book> list) {
		List<Book> bookList = new ArrayList<Book>();
		StringBuilder selectNoBookidSql = new StringBuilder(
				"select  b.* from user_book as ub,book b WHERE ub.book_id = b.id and ub.user_id =? ");
		for (int i = 0; i < list.size(); i++) {
			selectNoBookidSql.append(" and ub.book_id!='").append(list.get(i).getId()).append("'");
		}
		logger.debug(selectNoBookidSql);
		//		System.out.println(selectNoBookidSql);
		List<Map<String, Object>> maps1 = jdbcTemplate.queryForList(selectNoBookidSql.toString(), uid);
		for (Map<String, Object> map : maps1) {
			Book book = BookUtil.parseBook(map);
			if (book != null) {
				bookList.add(book);
			}
		}
		return bookList;
	}

	public ModelAndView getBookDetail(int uid, int bookid, HttpServletRequest request) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		Book book = null;
		String status = Status.SUCCESS;
		//		User user = (User) request.getSession().getAttribute("loginuser");
		//		if (user == null || uid != user.getId()) {
		//			return userService.notLoginView(modelView, modelMap);
		//		}
		//		if (uid == user.getId()) {
		book = getBookInfo(bookid);
		if (book == null) {
			status = Status.REJECTED + ":" + ErrorCode.BOOK_NOT_EXIST;
		}
		//		}
		modelMap.put("book", book);
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
		return modelView;
	}

}
